package rpc.frame.core.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import rpc.frame.core.data.RpcRequest;
import rpc.frame.core.data.RpcResponse;
import rpc.frame.core.spring.SpringBeanFactory;

import java.lang.reflect.Method;

/**
 * 重要*
 * 将客户端的请求 转化成实际的方法调用
 */
@Slf4j
public class RpcRequestHandler extends SimpleChannelInboundHandler<RpcRequest> {
    @Override
    public void channelRead0(ChannelHandlerContext ctx, RpcRequest rpcRequest) throws Exception {
        log.info("rpc 服务端接收到了请求",rpcRequest);
        RpcResponse rpcResponse = new RpcResponse();
        rpcResponse.setRequestId(rpcRequest.getRequestId());
        try {
            String interfaceName = rpcRequest.getClassName();
            String methodName=rpcRequest.getMethodName();
            Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
            Object[] parameters = rpcRequest.getParameters();
            //根基bean的名称 去spring ioc 容器获取bean
            Object bean = SpringBeanFactory.getBean(Class.forName(interfaceName));
            //根据方法名称 以及参数类型 获取到具体的方法
            Method method = bean.getClass().getMethod(methodName,parameterTypes);
            //调用方法
            Object result = method.invoke(bean,parameters);
            rpcResponse.setResult(result);
        } catch (Exception e) {
            log.error("rpc 服务端 转发异常 msg={}",e);
            rpcResponse.setCause(e);
        }finally {
            // 返回响应
            log.info("rpc服务端执行成功,返回的响应为;{}",rpcResponse);
            ctx.channel().writeAndFlush(rpcResponse);
        }

    }
}
